﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aspose.Cells;
using Mapster;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using SHZY.BaseData.Entitys.Common.Entity;
using SHZY.Business.Entitys.Common.Dto.PrintExecute;
using SHZY.Business.Entitys.Dto.pick;
using SHZY.Business.Entitys.Dto.pickrecord;
using SHZY.Business.Entitys.Entity;
using SHZY.Business.Interfaces;
using SHZY.ClayObject;
using SHZY.Common.Configuration;
using SHZY.Common.Core.Manager;
using SHZY.Common.Core.Manager.Files;
using SHZY.Common.Core.Security;
using SHZY.Common.Enum;
using SHZY.Common.Filter;
using SHZY.Common.FR;
using SHZY.Common.Models.NPOI;
using SHZY.Common.Security;
using SHZY.DataEncryption;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Interfaces.System;
using SqlSugar;

namespace SHZY.Business
{
    /// <summary>
    /// 业务实现：新打印记录.
    /// </summary>
    [ApiDescriptionSettings(Tag = "Business", Name = "QmsBusiPickRecord", Order = 200)]
    [Route("api/Business/[controller]")]
    public class QmsBusiPickRecordService : IQmsBusiPickRecordService, IDynamicApiController, ITransient
    {
        /// <summary>
        /// 服务基础仓储.
        /// </summary>
        private readonly ISqlSugarRepository<QmsBusiPickRecordEntity> _repository;

        /// <summary>
        /// 多租户事务.
        /// </summary>
        private readonly ITenant _db;

        /// <summary>
        /// 数据接口服务.
        /// </summary>
        private readonly IDataInterfaceService _dataInterfaceService;

        /// <summary>
        /// 用户管理.
        /// </summary>
        private readonly IUserManager _userManager;

        private readonly IFileManager _fileManager;

        /// <summary>
        /// 初始化一个<see cref="QmsBusiPickRecordService"/>类型的新实例.
        /// </summary>
        public QmsBusiPickRecordService(
            ISqlSugarRepository<QmsBusiPickRecordEntity> qmsBusiPickRecordRepository,
            IDataInterfaceService dataInterfaceService,
            ISqlSugarClient context,
            IUserManager userManager, IFileManager fileManager)
        {
            _repository = qmsBusiPickRecordRepository;
            _dataInterfaceService = dataInterfaceService;
            _db = context.AsTenant();
            _userManager = userManager;
            _fileManager = fileManager;
        }

        /// <summary>
        /// 获取新打印记录.
        /// </summary>
        /// <param name="id">主键值.</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<dynamic> GetInfo(string id)
        {
            return (await _repository.FirstOrDefaultAsync(x => x.Id == id)).Adapt<QmsBusiPickRecordInfoOutput>();
        }

        /// <summary>
        /// 获取新打印记录列表.
        /// </summary>
        /// <param name="input">请求参数.</param>
        /// <returns></returns>
        [HttpGet("GetList")]
        public async Task<dynamic> GetList([FromQuery] QmsBusiPickRecordListQueryInput input)
        {
            var data = await _repository.Context.Queryable<QmsBusiPickRecordEntity>()
                .WhereIF(!string.IsNullOrEmpty(input.no), it => it.No.Contains(input.no))
                .WhereIF(!string.IsNullOrEmpty(input.model), it => it.Model.Contains(input.model))
                .WhereIF(!string.IsNullOrEmpty(input.drawingNo), it => it.DrawingNo.Contains(input.drawingNo))
                .WhereIF(!string.IsNullOrEmpty(input.barcode), it => it.Barcode.Contains(input.barcode))
                .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.No.Contains(input.keyword) || it.Model.Contains(input.keyword) || it.DrawingNo.Contains(input.keyword) || it.Barcode.Contains(input.keyword))
                .Where(it => it.DeleteMark == null)
                .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.CreatorTime, OrderByType.Desc)
                .Select(it => new QmsBusiPickRecordListOutput
                {
                    id = it.Id,
                    no = it.No,
                    name = it.Name,
                    model = it.Model,
                    boxNo = it.BoxNo,
                    boxName = it.BoxName,
                    drawingNo = it.DrawingNo,
                    componentName = it.ComponentName,
                    specifications = it.Specifications,
                    unit = it.Unit,
                    qty = it.Qty,
                    remark = it.Remark,
                    barcode = it.Barcode,
                    printDate = it.PrintDate,
                }).OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
            return PageResult<QmsBusiPickRecordListOutput>.SqlSugarPageResult(data);
        }

        /// <summary>
        /// 打印记录无分页列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private async Task<dynamic> GetNoPageList([FromQuery] QmsBusiPickRecordListQueryInput input)
        {
            var data = await _repository.Context.Queryable<QmsBusiPickRecordEntity>()
                .WhereIF(!string.IsNullOrEmpty(input.no), it => it.No.Contains(input.no))
                .WhereIF(!string.IsNullOrEmpty(input.model), it => it.Model.Contains(input.model))
                .WhereIF(!string.IsNullOrEmpty(input.drawingNo), it => it.DrawingNo.Contains(input.drawingNo))
                .WhereIF(!string.IsNullOrEmpty(input.barcode), it => it.Barcode.Contains(input.barcode))
                .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.No.Contains(input.keyword) || it.Model.Contains(input.keyword) || it.DrawingNo.Contains(input.keyword) || it.Barcode.Contains(input.keyword))
                .Where(it => it.DeleteMark == null)
                .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.CreatorTime, OrderByType.Desc)
                .Select(it => new QmsBusiPickRecordListOutput
                {
                    id = it.Id,
                    no = it.No,
                    name = it.Name,
                    model = it.Model,
                    boxNo = it.BoxNo,
                    boxName = it.BoxName,
                    drawingNo = it.DrawingNo,
                    componentName = it.ComponentName,
                    specifications = it.Specifications,
                    unit = it.Unit,
                    qty = it.Qty,
                    remark = it.Remark,
                    barcode = it.Barcode,
                    printDate = it.PrintDate,
                }).OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort).ToListAsync();
            return data;
        }

        /// <summary>
        /// 导出打印记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("Actions/Export")]
        public async Task<dynamic> Export([FromQuery] QmsBusiPickRecordListQueryInput input)
        {
            var exportData = new List<QmsBusiPickRecordListOutput>();
            if (input.dataType == 0)
                exportData = Clay.Object(await GetList(input)).Solidify<PageResult<QmsBusiPickRecordListOutput>>().list;
            else
                exportData = await GetNoPageList(input);
            List<ParamsModel> paramList = "[{\"value\":\"做番号\",\"field\":\"no\"},{\"value\":\"单位名称\",\"field\":\"name\"},{\"value\":\"产品型号\",\"field\":\"model\"},{\"value\":\"箱号\",\"field\":\"boxNo\"},{\"value\":\"箱名\",\"field\":\"boxName\"},{\"value\":\"图号\",\"field\":\"drawingNo\"},{\"value\":\"部件名称\",\"field\":\"componentName\"},{\"value\":\"规格\",\"field\":\"specifications\"},{\"value\":\"单位\",\"field\":\"unit\"},{\"value\":\"数量\",\"field\":\"qty\"},{\"value\":\"备注\",\"field\":\"remark\"},{\"value\":\"条码\",\"field\":\"barcode\"},{\"value\":\"打印日期\",\"field\":\"printDate\"}]".ToList<ParamsModel>();
            ExcelConfig excelconfig = new ExcelConfig();
            excelconfig.FileName = "打印记录信息.xls";
            excelconfig.HeadFont = "微软雅黑";
            excelconfig.HeadPoint = 10;
            excelconfig.IsAllSizeColumn = true;
            excelconfig.ColumnModel = new List<ExcelColumnModel>();
            foreach (var item in input.selectKey.Split(',').ToList())
            {
                var isExist = paramList.Find(p => p.field == item);
                if (isExist != null)
                    excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value, Width = 25 });
            }

            var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
            ExcelExportHelper<QmsBusiPickRecordListOutput>.Export(exportData, excelconfig, addPath);
            var fileName = _userManager.UserId + "|" + addPath + "|xls";
            return new
            {
                name = excelconfig.FileName,
                url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fileName, "SHZY")
            };
        }

        /// <summary>
        /// 重打接口
        /// </summary>
        /// <param name="input"></param>
        /// <param name="exportType"></param>
        /// <returns></returns>
        [HttpPost("Actions/fastreportUpdatePrint")]
        public async Task<dynamic> UpdatePrint([FromBody] ComBasePrintExecuteCrInput input, FastReportExportType exportType = FastReportExportType.PDF)
        {
            //查询打印配置 获取打印模板文件和数据源SQL
            var printConfigData = await _repository.Context.Queryable<ComBasePrintConfigEntity>()
            .LeftJoin<ComBasePrintTemplateEntity>((x, a) => x.PrintTemplateId == a.Id && a.DeleteMark == null)
            .LeftJoin<ComBasePrintDataEntity>((x, a, b) => x.DataSourceId == b.Id && b.DeleteMark == null)
            .Where(x => x.Id == input.printConfigId)
            .Select((x, a, b) => new
            {
                PrintTemplateId = x.PrintTemplateId,
                TemplateFileInfo = a.FileInfo,
                IsCustomer = x.IsCustomer,
                dbLinkId = b.DbLinkId,
                dataSql = b.SqlTemplate,
                labelRuler = x.LabelRulerTemplate
            }).FirstAsync();
            if (printConfigData == null)
                throw Oops.Bah("未查找到相关打印配置!");
            #region 查找打印模板文件路径

            string fileInfoJson = printConfigData.TemplateFileInfo.ToString();
            // 判断是否匹配客户模板
            if (printConfigData.IsCustomer == 1)
            {
                var customerFile = await _repository.Context.Queryable<ComBasePrintTemplateCustomerEntity>()
                    .Where(x => x.CustomerId == input.formCustomerId && x.DeleteMark == null)
                    .Select(s => s.FileInfo).FirstAsync();

                fileInfoJson = customerFile.ToString();
            }

            // 获取模板文件名
            string filename = fileInfoJson.ToList<FileInfoModel>()[0].fileId;
            string filePath = Path.Combine(_fileManager.GetPathByType("annex"), filename);

            #endregion
            //数据源
            DataTable primary = await _repository.Context.Queryable<QmsBusiPickRecordEntity>().Where(it => it.Id == input.formDataId).Select(it => new QmsBusiPickEntity() { DrawingNo = it.DrawingNo, ComponentName = it.ComponentName, Specifications = it.Specifications, Item = it.Item, Barcode = it.Barcode, Qty = it.Qty }).ToDataTableAsync();
            Dictionary<string, DataTable> dicList = new Dictionary<string, DataTable>
            {
                { "PrintData", primary },
            };
            FileResult ms = CreateFR.ExportLabelFastReport(filePath, dicList, exportType);
            return ms;
        }
    }
}
